package cs.java.lang;

import java.io.IOException;
import java.util.Iterator;

import static cs.java.lang.Lang.list;

import cs.java.collections.GenericIterator;
import cs.java.collections.List;

public class TextImpl implements Text {

	private final StringBuilder value = new StringBuilder();

	public TextImpl(CharSequence... strings) {
		add(strings);
	}

	private void clear() {
		value.delete(0, length());
	}

	public Text add(CharSequence... strings) {
		for (CharSequence string : strings)
			value.append(string);
		return this;
	}

	public Text add(CharSequence string) {
		value.append(string);
		return this;
	}

	@Override public Object add(Object... objects) {
		for (Object object : objects)
			value.append(String.valueOf(object));
		return this;
	}

	@Override public Text addLine() {
		return add("\n");
	}

	@Override public Text addSpace() {
		return add(" ");
	}

	public Appendable append(char c) throws IOException {
		return value.append(c);
	}

	public Appendable append(CharSequence csq) throws IOException {
		return value.append(csq);
	}

	public Appendable append(CharSequence csq, int start, int end) throws IOException {
		return value.append(csq, start, end);
	}

	public Text caseDown() {
		set(toString().toLowerCase());
		return this;
	}

	public Text caseUp(int index) {
		set(value.substring(0, index) + value.substring(index, index + 1).toUpperCase()
				+ value.substring(index + 1, length()));
		return this;
	}

	public char charAt(int index) {
		return value.charAt(index);
	}

	public Text cut(int start, int end) {
		value.delete(start, end);
		return this;
	}

	public Text cutEnd(int length) {
		return cut(length() - length, length());
	}

	public Text cutStart(int length) {
		return cut(0, length);
	}

	public boolean isEmpty() {
		return value.length() == 0;
	}

	public Iterator<Character> iterator() {
		return new GenericIterator<Character>(length()) {
			@Override protected Character getValue() {
				return charAt(getIndex());
			}
		};
	}

	public int length() {
		return value.length();
	}

	public Text remove(String... strings) {
		String text = toString();
		for (String string : strings)
			text = text.replaceAll(string, "");
		set(text);
		return this;
	}

	public Text replace(String regex, String replace) {
		set(toString().replaceAll(regex, replace));
		return this;
	}

	public Text replaceEnd(String string) {
		cutEnd(string.length());
		add(string);
		return this;
	}

	public void set(CharSequence text) {
		clear();
		value.append(text);
	}

	public List<Text> split(String regex) {
		List<Text> split = list();
		for (String string : toString().split(regex))
			split.add(new TextImpl(string));
		return split;
	}

	public CharSequence subSequence(int start, int end) {
		return value.subSequence(start, end);
	}

	@Override public String toString() {
		return value.toString();
	}

	public Text trim() {
		set(toString().trim());
		return this;
	}
}
